﻿using System;
using System.Reactive.Disposables;
using Rsdn.SmartApp;

namespace Rsdn.Janus
{
    /// <summary>
    /// Обработчик команд форума.
    /// "Janus.Forum.SubscribeOrUnsubscribeForum"
    /// "Janus.Forum.Subscription"
    /// </summary>
    [CommandTarget]
    internal sealed class ForumCommandTarget : CommandTarget
    {
        public ForumCommandTarget(IServiceProvider serviceProvider)
            : base(serviceProvider) { }

        [CommandExecutor("Janus.Forum.SubscribeOrUnsubscribeForum")]
        public void ExecuteSubscribeOrUnsubscribeForum(
            ICommandContext context, int? forumId)
        {
            forumId = GetForumId(context, forumId);
            IRsdnForumService rsdnForumService = context.GetRequiredService<IRsdnForumService>();

            bool isForumSubscribed = rsdnForumService.IsForumSubscribed(forumId.Value);

            ForumSubscriptionRequest forumSubscriptionRequest = 
                new ForumSubscriptionRequest(forumId.Value, !isForumSubscribed);

            ForumSubscriptionRequest[] forumSubscriptionRequests =
                new[]
                    {
                        forumSubscriptionRequest
                    };

            ForumsSubscriptionHelper.UpdateForumsSubscriptions(context, forumSubscriptionRequests, true);
        }

        [CommandExecutor("Janus.Forum.Subscription")]
        public void ExecuteSubscription(ICommandContext context)
        {
            using (SubscribeForm subscribeForm = new SubscribeForm(context))
            {
                IUIShell uiShell = context.GetRequiredService<IUIShell>();
                subscribeForm.ShowDialog(uiShell.GetMainWindowParent());
            }
        }

        [CommandStatusGetter("Janus.Forum.SubscribeOrUnsubscribeForum")]
        public CommandStatus QueryForumCommandStatus(
            ICommandContext context, int? forumId)
        {
            if (forumId != null)
            {
                return CommandStatus.Normal;
            }

            var activeForumSvc = context.GetService<IActiveForumService>();
            return activeForumSvc != null && activeForumSvc.ActiveForum != null
                ? CommandStatus.Normal
                : CommandStatus.Unavailable;
        }

        [CommandStatusSubscriber("Janus.Forum.SubscribeOrUnsubscribeForum")]
        public IDisposable SubscribeForumCommandStatusChanged(
            IServiceProvider provider, Action handler)
        {
            var activeForumSvc = provider.GetService<IActiveForumService>();
            if (activeForumSvc != null)
            {
                SmartApp.EventHandler<IActiveForumService> statusUpdater = 
                    delegate
                        {
                            handler();
                        };

                activeForumSvc.ActiveForumChanged += statusUpdater;
                Action action = () => activeForumSvc.ActiveForumChanged -= statusUpdater;
                return Disposable.Create(action);
            }

            return Disposable.Empty;
        }

        private static int GetForumId(IServiceProvider provider, int? forumId)
        {
            if (forumId != null)
            {
                return forumId.Value;
            }

            IActiveForumService activeForumService = provider.GetRequiredService<IActiveForumService>();

            IForum currentForum = activeForumService.ActiveForum;

            return currentForum != null ? currentForum.ID : -1;
        }
    }
}